package com.myblog.demo.manager;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 通过这个类来记录当前用户的在线状态
 * 即维护 userId 与 WebSocketSession 之间的映射关系
 */

@Component
// 引入 Spring Boot 日志对象
@Slf4j
public class OnlineUserManager {

    /**
     * 用于储存 userId 与 WebSocketSession 之间的映射关系
     * 此次考虑线程安全问题，使用 ConcurrentHashMap
     */
    private final ConcurrentHashMap<Integer, WebSocketSession> sessionConcurrentHashMap = new ConcurrentHashMap<>();

    /**
     * 用户上线，储存 userId 和 WebSocketSession 到哈希表
     * @param userId 用户id
     * @param session WebSocket 会话
     */
    public void online(int userId, WebSocketSession session){
        // 处理多次登录的问题
        if(sessionConcurrentHashMap.get(userId) != null){
            // 说明用户已经在线了，登录失败，不记录这个映射关系
            log.info("[" + userId +"] 已经在线了，登录失败！");
        }
        sessionConcurrentHashMap.put(userId, session);
        log.info("[" + userId +"] 上线！");
    }

    /**
     * 用户下线，从哈希表中移除 userId 和 session 之间的映射关系
     * @param userId 用户id
     * @param session WebSocket 会话
     */
    public void offline(int userId, WebSocketSession session){
        // 首先确保删除的是自己的会话
        WebSocketSession existSession = sessionConcurrentHashMap.get(userId);
        if(session == existSession){
            // 如果是同一个会话，才删除
            sessionConcurrentHashMap.remove(userId);
            log.info("[" + userId +"] 下线！");
        }
    }

    /**
     * 根据用户id 获取 WebSocketSession
     * @param userId 用户id
     * @return WebSocketSession
     */
    public WebSocketSession getSession(int userId){
        return sessionConcurrentHashMap.get(userId);
    }
}
